package com.zxy.supplier_system.server.controller

import com.zxy.supplier_system.server.entity.Authority
import com.zxy.supplier_system.server.entity.Employee
import com.zxy.supplier_system.server.entity.EmployeeSetting
import com.zxy.supplier_system.server.service.EmployeeService
import com.zxy.supplier_system.server.utils.IntIdAndName
import com.zxy.supplier_system.server.utils.StringIdAndName
import com.zxy.supplier_system.server.utils.toStringIdAndName
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.web.bind.annotation.*
import java.security.Principal
import java.time.OffsetDateTime

@RestController
@RequestMapping("employees")
class EmployeeController(
    private val employeeService: EmployeeService,
) {

    @GetMapping("me")
    fun getMe(principal: Principal): MeResponse {
        val employee = (principal as UsernamePasswordAuthenticationToken).principal as Employee
        return MeResponse(
            employee.id!!,
            employee.name,
            employee.authorities,
            employee.systemService.toStringIdAndName(),
            EmployeeSettingResponse.fromEmployeeSetting(employee.setting),
        )
    }

    class MeResponse(
        val id: Int,
        val name: String,
        val authorities: List<Authority>,
        val systemService: StringIdAndName,
        val setting: EmployeeSettingResponse,
    )

    data class EmployeeSettingResponse(
        val subscribeAllMarketOrderSubmittedWechatNotification: Boolean,
    ) {
        companion object {
            fun fromEmployeeSetting(setting: EmployeeSetting): EmployeeSettingResponse {
                return EmployeeSettingResponse(
                    setting.subscribeAllMarketOrderSubmittedWechatNotification,
                )
            }
        }
    }

    data class UpdateEmployeeSettingRequest(
        val subscribeAllMarketOrderSubmittedWechatNotification: Boolean,
    )

    @PostMapping("me/setting")
    fun updateSetting(@RequestBody updateEmployeeSettingRequest: UpdateEmployeeSettingRequest){
        this.employeeService.updateSetting(updateEmployeeSettingRequest)
    }

    data class QueryEmployeeRequest(
        val name: String?,
        val phoneNumber: String?,
        val roleIds: List<Int> = emptyList(),
        val marketName: String? = null,
        val searchInput: String? = null,
    )

    @GetMapping
    @HasAuthority(Authority.人员_查询)
    fun queryEmployees(queryEmployeeRequest: QueryEmployeeRequest, pageable: Pageable): Page<EmployeeResponse> {
        return this.employeeService.queryEmployees(queryEmployeeRequest, pageable)
    }

    data class EmployeeResponse(
        val id: Int,
        val name: String,
        val phoneNumber: String,
        val roles: List<IntIdAndName>,
        val createdDateTime: OffsetDateTime,
        var enabled: Boolean,
    )

    data class CreateEmployeeRequest(
        val name: String,
        val phoneNumber: String,
        val roleIds: List<Int>,
        val password: String?
    )

    @PostMapping
    @HasAuthority(Authority.人员_新增)
    fun createEmployee(@RequestBody createEmployeeRequest: CreateEmployeeRequest): CreateEmployeeResponse {
        return this.employeeService.createEmployee(createEmployeeRequest)
    }

    data class CreateEmployeeResponse(
        val password: String,
    )

    data class UpdateEmployeeRequest(
        val name: String,
        val phoneNumber: String,
        val roleIds: List<Int>,
    )

    @PutMapping("{id}")
    @HasAuthority(Authority.人员_修改)
    fun updateEmployee(@PathVariable id: Int, @RequestBody updateEmployeeRequest: UpdateEmployeeRequest) {
        this.employeeService.updateEmployee(id, updateEmployeeRequest)
    }

    @HasAuthority(Authority.人员_启用)
    @PatchMapping("{id}/enable")
    fun enableEmployee(@PathVariable id: Int){
        this.employeeService.enableEmployee(id)
    }

    @HasAuthority(Authority.人员_禁用)
    @PatchMapping("{id}/disable")
    fun disableEmployee(@PathVariable id: Int){
        this.employeeService.disableEmployee(id)
    }

    @GetMapping(params = ["sort=saleManager", "projection=summary"])
    fun getEmployeeSummariesSortBySaleManager(): List<IntIdAndName> {
        return employeeService.getEmployeeSummariesSortBySaleManager()
    }

    data class UpdatePasswordRequest(
        val password: String,
    )

    @PatchMapping("me/password")
    fun setPassword(@RequestBody updatePasswordRequest: UpdatePasswordRequest) {
        return this.employeeService.setPassword(updatePasswordRequest)
    }

    @HasAnyAuthority(Authority.人员_操作记录_查询)
    @GetMapping(params = ["projection=summary"])
    fun getEmployeeSummaries(): List<IntIdAndName> {
        return employeeService.getAllSummaries()
    }

    @GetMapping("{id}")
    fun getEmployeeDetail(@PathVariable id: Int): EmployeeDetailResponse {
        return employeeService.getEmployeeDetail(id)
    }

    class EmployeeDetailResponse(
        val id: Int,
        val name: String,
        val phoneNumber: String,
        val roles: List<IntIdAndName>,
        val createdDateTime: OffsetDateTime,
        val createdBy: IntIdAndName? = null
    )


}